#include "windowLogin.h"
#include "windowInit.h"
#include "windowRooms.h"
#include "singleSocket.h"
#include <jsoncpp/json.h>
#include "user.h"

using std::string;
using std::vector;

windowLogin::windowLogin(sdlScreen& screen): window::window(screen){
	this->background.load("backgroundLogin.png");
	this->imgUser.load("imagenUser.gif");
	this->imgPass.load("imagenPass.gif");
	this->botInputU.load("botonInput.gif");
	this->botInputP.load("botonInput.gif");
	this->botAccept.load("botonAceptar.gif");
	this->botBack.load("botonVolver.gif");
	this->sndBotClick.load("botClicked.wav");
	this->entradaU.setFilter(normal);
	this->entradaP.setFilter(asterisk);
	this->writingUser = false;
	this->writingPass = false;
}

void windowLogin::show(){
	this->screen.applySurface(0,0,this->background);
	int actWidth = screen.width() - botBack.width();
	int actHeight = screen.height() - botBack.height();
	this->screen.applySurface(actWidth, actHeight, this->botBack);
	this->botBack.setPosition(actWidth,actHeight);
	actWidth = 0;
	actHeight = screen.height() - botAccept.height();
	this->screen.applySurface(actWidth, actHeight, this->botAccept);
	this->botAccept.setPosition(actWidth,actHeight);
	actWidth = (screen.width() - imgUser.width())/2;
	actHeight = 20;
	this->screen.applySurface(actWidth, actHeight, this->imgUser);
	actWidth = (screen.width() - botInputU.width())/2;
	actHeight += this->imgUser.height() + 25; 
	this->screen.applySurface(actWidth, actHeight, this->botInputU);
	this->botInputU.setPosition(actWidth,actHeight);
	int x, y;
	this->botInputU.getPosition(x,y);
	x += (this->botInputU.width() - this->entradaU.width())/2;
	y += (this->botInputU.height() - this->entradaU.height())/2;
	this->screen.applySurface(x,y,this->entradaU);
	actWidth = (screen.width() - imgPass.width())/2;
	actHeight += 100;
	this->screen.applySurface(actWidth, actHeight, this->imgPass);
	actWidth = (screen.width() - botInputP.width())/2;
	actHeight += this->imgPass.height() + 25; 
	this->screen.applySurface(actWidth, actHeight, this->botInputP);
	this->botInputP.setPosition(actWidth,actHeight);
	this->botInputP.getPosition(x,y);
	x += (this->botInputP.width() - this->entradaP.width())/2;
	y += (this->botInputP.height() - this->entradaP.height())/2;
	this->screen.applySurface(x,y,this->entradaP);
	this->screen.refresh();
}

void windowLogin::handleBotInput(vector<sdlStringInput*>& vInputs,
	vector<bool*>& vBools, unsigned pos){
	for (vector<bool*>::iterator i = vBools.begin(); i != vBools.end(); ++i){
		**i = false;	
	}
	*vBools[pos] = true;
	SDL_Event fooEvent;
	fooEvent.type=SDL_KEYDOWN;
	fooEvent.key.keysym.sym = SDLK_RETURN;
	for (vector<sdlStringInput*>::iterator it = vInputs.begin();
	it != vInputs.end(); ++it){
		(*it)->handleEvent(fooEvent);
	}
	fooEvent.key.keysym.sym = SDLK_UNDERSCORE;
	vInputs[pos]->handleEvent(fooEvent);
	this->show();
}

window* windowLogin::handleBotAccept(vector<sdlStringInput*>& vInputs,
vector<bool*>& vBools, string& imgErrorPath){
	window* win = NULL;
	for (vector<bool*>::iterator i = vBools.begin(); i != vBools.end(); ++i){
		**i = false;		
	}
	SDL_Event fooEvent;
	fooEvent.type=SDL_KEYDOWN;
	fooEvent.key.keysym.sym = SDLK_RETURN;
	for (vector<sdlStringInput*>::iterator it = vInputs.begin();
	it != vInputs.end(); ++it){
		(*it)->handleEvent(fooEvent);
	}
	this->show();
	if (this->procesarDatos()){
		win = new windowRooms(this->screen);
	} else {
		sdlImage error;
		error.load(imgErrorPath);
		int x = (this->screen.width() - error.width())/2;
		int y = (this->screen.height() - error.height())/2;
		this->screen.applySurface(x,y,error);
		this->screen.refresh();
		SDL_Delay(1500);
		this->show();
	}
	return win;
}

window* windowLogin::handleBotBack(){
	this->sndBotClick.play();
	SDL_Delay(300); // Vale la espera? es para el sonido
	return new windowInit(this->screen);
}

window* windowLogin::handleReturn(vector<sdlStringInput*>& vInputs,
vector<bool*>& vBools){
	SDL_Event event;
	event.type=SDL_KEYDOWN;
	event.key.keysym.sym = SDLK_RETURN;
	vector<sdlStringInput*>::iterator it = vInputs.begin();
	bool wasLast = false;
	for (vector<bool*>::iterator i = vBools.begin(); i != vBools.end(); ++i){
		if (**i){
			(*it)->handleEvent(event);
		}
		wasLast = **i;
		**i = false;
		it++;
	}
	this->show();
	if (wasLast){
		string path("errorUserPass.gif");
		return this->handleBotAccept(vInputs,vBools,path);
	}
	return NULL;
}

void windowLogin::handleTab(vector<sdlStringInput*>& vInputs,
vector<bool*>& vBools){
	for (vector<bool*>::iterator it = vBools.begin();it != vBools.end();it++){
		if (**it){
			unsigned pos = (it - vBools.begin()) +1;
			if (pos >= vInputs.size()){pos = 0;}
			this->handleBotInput(vInputs,vBools,pos);
			break;
		}
	}
}

bool windowLogin::handleEvent(const SDL_Event& event, window*& win){
	win = NULL;
	bool b = false; //Vale true si la venta entendió el evento
	vector<sdlStringInput*> vInputs;
	vInputs.push_back(&(this->entradaU));
	vInputs.push_back(&(this->entradaP));
	vector<bool*> vBools;
	vBools.push_back(&(this->writingUser));
	vBools.push_back(&(this->writingPass));
	if (event.type == SDL_MOUSEBUTTONDOWN){
		if (event.button.button == SDL_BUTTON_LEFT){
			if (this->botBack.wasClicked(event)){
				this->sndBotClick.play();
				win = this->handleBotBack();
				SDL_Delay(150); // Vale la espera?
				b = true;
			} else if (this->botInputU.wasClicked(event)){
				this->handleBotInput(vInputs, vBools, 0);
				b = true;
			} else if (this->botInputP.wasClicked(event)){
				this->handleBotInput(vInputs, vBools, 1);
				b = true;
			} else if (this->botAccept.wasClicked(event)){
				this->sndBotClick.play();
				string path("errorUserPass.gif");
				win = this->handleBotAccept(vInputs,vBools,path);
				SDL_Delay(150);
				b = true;
			}
		}
	} else if (event.type == SDL_KEYDOWN){
		if (event.key.keysym.sym == SDLK_RETURN || event.key.keysym.sym == SDLK_KP_ENTER){
			win = this->handleReturn(vInputs,vBools);
			b = true;
		} else if (event.key.keysym.sym == SDLK_TAB){
			this->handleTab(vInputs,vBools);
			b = true;
		} else if (this->writingUser){
			b = this->entradaU.handleEvent(event);
			this->show();
		} else if (this->writingPass){
			b = this->entradaP.handleEvent(event);
			this->show();
		}
	}
	return b;
}

bool windowLogin::procesarDatos(){
	Json::Value root;
	root["Opcion"] = "Iniciar sesion";
	root["Nombre de usuario"] = this->entradaU.getTexto();
	root["Contrasenia"] = this->entradaP.getTexto();
	singleSocket* socket = singleSocket::getInstance();
	if (!socket->conectado()){socket->conectar();}
	socket->enviar(root);

	Json::Value rootRespuesta;
	socket->recibir(rootRespuesta);
	string resultado = rootRespuesta.get("Respuesta", "").asString();
	if(resultado != "Ingreso exitoso"){return false;}
	User* user = User::getInstance();
	user->setName(this->entradaU.getTexto());
	user->setPass(this->entradaP.getTexto());
	return true;
}

windowLogin::~windowLogin(){}
